/* Soubor je ulozen v kodovani UTF-8.
 * Kontrola kódování: Příliš žluťoučký kůň úpěl ďábelské ódy. */

package cz.vse.adventura.po1715.xforv00_forejt.hra;

import cz.pecinovsky.english.pojj.adv_framework.game_gui.IObjectG;
import cz.pecinovsky.english.pojj.adv_framework.game_gui.IPlaceG;
import java.awt.Point;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;





/*******************************************************************************
 * Instance třídy {@code Místnost} představují jednotlivé místnosti ve hře
 *
 * @author    Vladimír Forejt
 * @version   0.00.000
 */
public class Místnost implements IPlaceG
{
//== KONSTANTNÍ ATRIBUTY TŘÍDY =================================================
//== PROMĚNNÉ ATRIBUTY TŘÍDY ===================================================
//== STATICKÝ INICIALIZAČNÍ BLOK - STATICKÝ KONSTRUKTOR ========================
//== KONSTANTNÍ ATRIBUTY INSTANCÍ ==============================================
    private final String název;
    private final String popis;
    private final Point position;



//== PROMĚNNÉ ATRIBUTY INSTANCÍ ================================================

    /** Sousedé dané místnosti */
    private Set<Místnost> sousedé = new HashSet<Místnost>();

    /** Předměty nacházející se aktuálně v místnosti. */
    private Collection<Předmět>  předměty = new ArrayList<Předmět>();

//== PŘÍSTUPOVÉ METODY VLASTNOSTÍ TŘÍDY ========================================
//== OSTATNÍ NESOUKROMÉ METODY TŘÍDY ===========================================

//##############################################################################
//== KONSTRUKTORY A TOVÁRNÍ METODY =============================================

    /***************************************************************************
     * @param název, popis, výchozí předměty
     */
    public Místnost(String název, String popis, String[] předměty, Point position)
    {
        this.název = název;
        this.popis = popis;
        this.position = position;
        for (int i=0; i<předměty.length; i++ )
        {
           Předmět předmět = new Předmět(předměty[i]);
           this.předměty.add (předmět);
        }

      }



//== ABSTRAKTNÍ METODY =========================================================
//== PŘÍSTUPOVÉ METODY VLASTNOSTÍ INSTANCÍ =====================================

    /**
     * Nastaví sousední prostor. Vzhledem k tomu, že je použit
     * Set pro uložení východů, může být sousední místnost uvedena pouze jednou
     * (tj. nelze mít dvoje dveře do stejné sousední místnosti). Druhé zadání
     * stejné místnosti tiše přepíše předchozí zadání (neobjeví se žádné chybové hlášení).
     * Lze zadat též cestu ze do sebe sama.
     *
     * @param soused - mistnost, ktera sousedi s aktualni mistnosti.
     *
     */
    void setSoused(Místnost soused) {
        sousedé.add(soused);
    }


     /***************************************************************************
     * Vrátí název místnosti.
     *
     * @return Název místnosti
     */
    @Override
    public String getName()
     {
         return název;
     }


    /***************************************************************************
     * Vrátí popis místnosti, který danou místnost stručné charakterizuje.
     *
     * @return Požadovaný popis
     */
    @Override
    public String getDescription()
     {
         return popis;
     }


    /***************************************************************************
     * Vrátí kolekci předmětů nacházejících se v dané místnosti.
     *
     * @return Požadovaná kolekce
     */
    @Override
    public Collection<? extends IObjectG> getObjects()
     {
         return Collections.unmodifiableCollection(předměty);
     }


    /***************************************************************************
     * Vrátí kolekci místností, do nichž je možno se z teto místnosti přesunout.
     *
     * @return Požadovaná kolekce
     */
    @Override
    public Collection<? extends IPlaceG> getNeighbors()
     {
         return Collections.unmodifiableCollection(sousedé);
     }

     /***************************************************************************
     * Vrátí true / false na dotaz, jestli je daná místnost sousedem
     *
     * @param potenciální soused
     * @return Požadovaná kolekce
     */

    boolean isSoused (Místnost soused)
    {
        boolean výsledek = false;
        for (Místnost místnost : sousedé) {
            if (místnost.getName().equalsIgnoreCase(soused.getName())) {
                výsledek = true;
                break;
            }
        }
        return výsledek;
    }

    /***************************************************************************
     * Vrátí pozici místnosti na plánu hry,
     * presněji pozici hráče nacházejícícho se v dané místnosti.
     * Na této pozici bude hráč při pobytu v dané místnosti zobrazen.
     *
     * @return Požadovaná pozice
     */
    @Override
    public Point getPosition()
    {
       return new Point(position);
    }

//== OSTATNÍ NESOUKROMÉ METODY INSTANCÍ ========================================

/***************************************************************************
     * Odlozi zadany predmet v mistnosti.
     *
     * @param  predmet odkladany v mistnosti
     * @return {@code true} pokud byl predmet do mistnosti vlozen
     */

    void polož( Předmět předmět ) {
        předměty.add( předmět );
        SprávceMístností.getSprávceMístností().noticeObjectListeners();
    }

/***************************************************************************
* Zvedne předmět z místnosti, vrátí odkaz na něj
*
* @param  predmet odkladany v mistnosti
* @return {@code true} pokud byl predmet do mistnosti vlozen
*/
    Předmět zvedni (String nazev)
    {
        Předmět požadovaný = null;
        for(Předmět objekt : předměty)
        {
            if(objekt.getName().equalsIgnoreCase(nazev)) {
                if( objekt.isTransportable()) {
                    požadovaný = objekt;
                    předměty.remove(objekt);
                    SprávceMístností.getSprávceMístností().noticeObjectListeners();
                } else {
                    požadovaný =  Předmět.TIHA;
                }
                break;
            }
        }
        return požadovaný;
    }




/***************************************************************************
* Vrátí název dané instance.
*
* @return Nazev instance
*/
    @Override
    public String toString()
    {
        return název;
    }

//== SOUKROMÉ A POMOCNÉ METODY TŘÍDY ===========================================
//== SOUKROMÉ A POMOCNÉ METODY INSTANCÍ ========================================
//== INTERNÍ DATOVÉ TYPY =======================================================
//== TESTY A METODA MAIN =======================================================
//
//     /***************************************************************************
//      * Testovací metoda.
//      */
//     public static void test()
//     {
//         Místnost instance = new Místnost();
//     }
//     /** @param args Parametry příkazového řádku - nepoužívané. */
//     public static void main(String[] args)  {  test();  }
}
